/**
 * @file PictureState.hpp
 *
 * @date 19/12/2011
 * @author Tales 
 *
 */

#ifndef _MODEL_PICTURESTATE_HPP_
#define _MODEL_PICTURESTATE_HPP_

#include <vector>
#include <SDL.h>
#include "Layer.hpp"

namespace yep
{
using namespace std;

/**
 * @brief Um estado de uma Picture.
 *
 * Esta é uma classe "privada" deste módulo. Para manipulá-la fora, utilize as classes Picture
 * e qualquer derivada de Command.
 */
class PictureState
{
public:
	/**
	 * @brief Construtor.
	 */
	PictureState(Uint16 w, Uint16 h, Uint8 bpp);

	/**
	 * @brief Construtor default.
	 */
	PictureState();

	/**
	 * @brief Destrutor.
	 */
	~PictureState();

	/**
	 * @brief Retorna um layer
	 * @param index a posição deste layer
	 * @return uma referência
	 * @throw Error se index > getLayerCount()
	 */
	Layer &getLayer(size_t index);

	/**
	 * @brief Retorna a quantidade de layers.
	 * @return
	 */
	size_t getLayerCount();

	/**
	 * @brief Adiciona um novo layer
	 * @throw Error se houver um erro na alocação do layer
	 *
	 * Cria um novo layer "vazio". Internamente uma nova superfície é alocada.
	 */
	void addLayer();

	/**
	 * @brief Adiciona um novo layer
	 * @param surface se diferente de null, é utilizada como camada. Este método considera de posse da imagem, portanto,
	 *  responsável por liberar sua memória. Se for igual a null, a classe cria sua própria surface.
	 * @throw Error se as características da superfície for diferente da do estado.
	 */
	void addLayer(SDL_Surface *surface);

	/**
	 * @brief Remove quantidade especificadas de camadas.
	 * @param qtd a quantidade
	 *
	 * Ele sempre remove a(s) última(s) camadas (que estão no topo).
	 */
	void removeLayer(size_t qtd);

	/**
	 * Intercambia a posição de duas camadas.
	 * @param l1 será colocado no lugar de l2.
	 * @param l2 será colocado no lugar de l1.
	 */
	void swap(size_t l1, size_t l2);

	/**
	 * @brief Retorna a quantidade de bits per-pixel
	 */
	Uint8 getBpp() const;

	/**
	 * @brief Retorna a altura
	 */
	Uint16 getH() const;

	/**
	 * @brief Retorna a largura
	 */
	Uint16 getW() const;

	/**
	 * @brief Altera a quantidade de bits per pixel
	 *
	 * @b IMPORTANTE: esse é apenas um valor que se espera que as camadas tenham (usado para checagem)
	 *  este método @b não altera os layers existentes.
	 */
	void setBpp(Uint8 bpp);

	/**
	 * @brief Altera a altura
	 *
	 * @b IMPORTANTE: esse é apenas um valor que se espera que as camadas tenham (usado para checagem)
	 *  este método @b não altera os layers existentes.
	 */
	void setH(Uint16 h);

	/**
	 * @brief Altera a largura
	 *
	 * @b IMPORTANTE: esse é apenas um valor que se espera que as camadas tenham (usado para checagem)
	 *  este método @b não altera os layers existentes.
	 */
	void setW(Uint16 w);

private:
	Uint16 w;
	Uint16 h;
	Uint8 bpp;
	vector<Layer> layers;
};

} /* namespace yep */
#endif /* _MODEL_PICTURESTATE_HPP_ */
